[pyupgrade] Fix false positive on relative imports from local .builtins module (UP029)#21309
Merged
MichaReiser merged 1 commit intoastral-sh:mainfrom Nov 7, 2025
Merged
Conversation
Contributor
|
amyreese
approved these changes
Nov 7, 2025
dcreager
added a commit
that referenced
this pull request
Nov 7, 2025
* origin/main: Remove duplicate preview tests for `FURB101` and `FURB103` (#21303) [ty] Add support for `Literal`s in implicit type aliases (#21296) [ty] Add missing `heap_size` to `variance_of` queries (#21318) [`pyupgrade`] Fix false positive on relative imports from local `.builtins` module (`UP029`) (#21309) [ty] Make range/position conversions fallible (#21297) Bump 0.14.4 (#21306) Fix main by using `infer_expression` (#21299) [ty] Understand legacy and PEP 695 `ParamSpec` (#21139) [ty] Discover site-packages from the environment that ty is installed in (#21286) [ty] Make special cases for `UnionType` slightly narrower (#21276) Require ignore 0.4.24 in `Cargo.toml` (#21292) [ty] Favour imported symbols over builtin symbols (#21285) docs: revise Ruff setup instructions for Zed editor (#20935) [ty] Update salsa (#21281) [syntax-error]: no binding for nonlocal PLE0117 as a semantic syntax error (#21032)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes false positive where
UP029incorrectly flagged relative imports from local modules namedbuiltins(e.g.,from .builtins import next) as unnecessary builtin imports. The rule should only flag imports from Python's standardbuiltinsmodule, not from local modules.Fixes #21307
Problem Analysis
The
UP029rule checks for unnecessary imports from Python'sbuiltinsmodule. However, it was incorrectly flagging relative imports likefrom .builtins import nextas unnecessary, even though these are importing from a local module namedbuiltins, not Python's builtins module.The bug occurred because the rule only checked if the module name matched
"builtins"without distinguishing between:from builtins import next(should be flagged)from .builtins import next(should NOT be flagged)This caused issues in projects like
aioitertoolsthat reimplement builtins as async-compatible variants in a local.builtinsmodule.Approach
The fix adds a check for relative imports by:
level: u32parameter to theunnecessary_builtin_importfunction to detect import levellevel > 0(indicating a relative import) before checking the module namelevelparameter from the AST nodeThis ensures that relative imports are skipped entirely, as they're importing from local modules, not Python's builtins. Absolute imports continue to work correctly and are still flagged as expected.
The fix is minimal and surgical - it only adds the relative import check without modifying any existing logic for absolute imports.